/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hps.model;

import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import javax.swing.ImageIcon;

/**
 *
 * @author $Author: NIKE3500 $
 * @version $Revision: 93 $
 * @date $Date: 2013-01-21 12:54:56 +0000 (Mon, 21 Jan 2013) $
 */
public class EmergencyExit implements IInfluence
{

    public static final int EXIT_RANGE = 15; // Entspricht einer direkten Reichweite von 8m
    private static Image exitImage = null;
    //Member
    private ArrayList<Point> influencePoint;
    private ArrayList<Point> exitPoints;
    private ArrayList<IInfluence> me;
    private Point startPoint, endPoint;

    public EmergencyExit(Point p1, Point p2)
    {
        if ((p1.getX() != p2.getX()) && (p1.getY() != p2.getY()))
        {
            throw new IllegalArgumentException("Wand muss gerade sein");
        }
        exitPoints = new ArrayList<Point>();
        me = new ArrayList<IInfluence>();
        me.add(this);
        //Belegte Felder einrichten
        if (p1.getX() == p2.getX())
        {
            startPoint = p1.getY() <= p2.getY() ? p1 : p2;
            endPoint = p1.getY() <= p2.getY() ? p2 : p1;
        }
        else
        {
            startPoint = p1.getX() <= p2.getX() ? p1 : p2;
            endPoint = p1.getX() <= p2.getX() ? p2 : p1;
        }
        for (int i = startPoint.getX(); i <= endPoint.getX(); i++)
        {
            for (int j = startPoint.getY(); j <= endPoint.getY(); j++)
            {
                exitPoints.add(new Point(i, j));
            }
        }
    }

    @Override
    public void setInfluence(FloorField field)
    {
        int lenPoints = exitPoints.size();
        byte[][] byteField = field.getField();
        for (Point p : exitPoints)
        {
            byteField[p.getX()][p.getY()] = Byte.MAX_VALUE;
        }

        for (int i = 1; i <= EXIT_RANGE; i++)
        {
            influencePoint = calcInfluencePoints(new Point(startPoint.getX() - i, startPoint.getY() + i), new Point(endPoint.getX() + i, endPoint.getY() - i));

            for (Point p : influencePoint)
            {
                if ((p.getX() >= 0)
                        && (p.getY() >= 0)
                        && (p.getX() < byteField.length)
                        && (p.getY() < byteField[0].length))
                {
                    if ((Byte.MAX_VALUE - (Byte.MAX_VALUE - 7 * i)) >= 0)
                    {
                        if (byteField[p.getX()][p.getY()] < (Byte.MAX_VALUE-1 - (Byte.MAX_VALUE - 7 * i)))
                        {
                            byteField[p.getX()][p.getY()] += (byte) (Byte.MAX_VALUE-1 - (7 * i));
                        }
                        else
                        {
                            byteField[p.getX()][p.getY()] = Byte.MAX_VALUE-1;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

        }

        field.setField(byteField);
//        for (int h = 0; h < byteField.length; h++)
//        {
//            for (int l = 0; l < byteField[0].length; l++)
//            {
//                System.out.print(byteField[l][h] + " ");
//            }
//            System.out.println();
//        }




        //}
    }

    /**
     * Notausgaenge verursachen keinen Schaden.
     *
     * @param pedestrians
     */
    @Override
    public void damage(ArrayList<Pedestrian> pedestrians)
    {
        //Notausgaenge verursachen keinen Schaden.
    }

    @Override
    public ArrayList<IInfluence> spread(IInfluence[][] blocked)
    {
        return me;
    }

    @Override
    public int getBlocked(Point p)
    {
        return 0;
    }

    @Override
    public ArrayList<Point> getBlockedFields()
    {
        return new ArrayList<Point>();
    }

    @Override
    public boolean isBlocking()
    {
        return false;
    }

    @Override
    public boolean isAt(Point pos)
    {
        for (int i = 0; i < exitPoints.size(); i++)
        {
            if (exitPoints.get(i).equals(pos))
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public IInfluence clone()
    {
        return new EmergencyExit(startPoint, endPoint);
    }

    @Override
    public void draw(Graphics g, Point roomPosition, int singleFieldSize)
    {
        if (exitImage == null)
        {
            exitImage = new ImageIcon(getClass().getResource("/hps/view/HPS_icons/notausgang.png")).getImage();
        }
        for (int i = 0; i < exitPoints.size(); i++)
        {
            g.drawImage(exitImage,
                    roomPosition.getX() + this.exitPoints.get(i).getX() * singleFieldSize + 1,
                    roomPosition.getY() + this.exitPoints.get(i).getY() * singleFieldSize + 1,
                    singleFieldSize, singleFieldSize, null);
        }
    }

    @Override
    public boolean equals(Object o)
    {
        if (o == null)
        {
            return false;
        }
        if (!(o instanceof EmergencyExit))
        {
            return false;
        }
        if (!(o.hashCode() == this.hashCode()))
        {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 97 * hash + (this.exitPoints != null ? this.exitPoints.hashCode() : 0);
        return hash;
    }

    /**
     * Liefert alle Ausgangspunkte des Notausgangs
     *
     * @return
     */
    public ArrayList<Point> getExitPoints()
    {
        return (ArrayList<Point>) exitPoints.clone();
    }

    private boolean isVertical()
    {
        if ((startPoint.getX() != endPoint.getX()) && (startPoint.getY() == endPoint.getY()))
        {
            return true;
        }
        return false;
    }

    private boolean isHorizontal()
    {
        if ((startPoint.getX() == endPoint.getX()) && (startPoint.getY() != endPoint.getY()))
        {
            return true;
        }
        return false;
    }

//    public static void main(String args[])
//    {
//        FloorField f = new FloorField(EXIT_RANGE, EXIT_RANGE);
//        EmergencyExit e = new EmergencyExit(new Point(10, 10), new Point(10, 13));
//        e.setInfluence(f);
//
//    }
    private ArrayList<Point> calcInfluencePoints(Point upperLeft, Point lowerRight)
    {
        ArrayList<Point> influencePoints = new ArrayList<Point>();

        for (int i = upperLeft.getX(); i <= lowerRight.getX(); i++)
        {
            influencePoints.add(new Point(i, upperLeft.getY()));
            influencePoints.add(new Point(i, lowerRight.getY()));
        }
        for (int i = lowerRight.getY(); i <= upperLeft.getY(); i++)
        {
            influencePoints.add(new Point(upperLeft.getX(), i));
            influencePoints.add(new Point(lowerRight.getX(), i));
        }

        influencePoints.remove(upperLeft);
        influencePoints.remove(lowerRight);
        influencePoints.remove(new Point(upperLeft.getX(), lowerRight.getY()));
        influencePoints.remove(new Point(lowerRight.getX(), upperLeft.getY()));

        return influencePoints;
    }
}
